package cn.xmoit.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;

import javax.sql.DataSource;

/**
 * @author fangyy
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	/**
	 * 数据源 DataSource
	 */
	@Autowired
	private DataSource dataSource;

	@Override
	@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}

	@Bean
	public static NoOpPasswordEncoder passwordEncoder() {
		return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
	}

	/// **
	// * 在非数据库的情况下，可以使用这种方式配置用户信息
	// * @return
	// */
	// @Override
	// protected UserDetailsService userDetailsService() {
	// InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
	// manager.createUser(User.withUsername("admin").password("123456").roles("ADMIN").build());
	// manager.createUser(User.withUsername("user").password("123456").roles("USER").build());
	// return manager;
	// }

	/**
	 * 在使用数据库的情况下，可以使用这种方式配置用户信息
	 * @param auth AuthenticationManagerBuilder
	 * @throws Exception 异常信息
	 */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource);
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http // 配置登录页并允许访问
			.formLogin()
			.usernameParameter("username")
			.passwordParameter("password")
			.loginPage("/login")
			// 配置Basic登录
			// .and().httpBasic()
			// 配置登出页面
			.and()
			.logout()
			.logoutUrl("/logout")
			.logoutSuccessUrl("/")

			// 开放接口访问权限，不需要登录授权就可以访问
			.and()
			.authorizeRequests()
			.antMatchers("/oauth/**", "/login/**", "/logout/**")
			.permitAll()

			// 其余所有请求全部需要鉴权认证
			.anyRequest()
			.authenticated()

			// 开启记住我功能，登陆成功以后，将cookie发给浏览器保存，以后访问页面带上这个cookie，只要通过检查就可以免登录
			.and()
			.rememberMe()
			.rememberMeParameter("remember-me")

			// 关闭跨域保护;
			.and()
			.csrf()
			.disable();
	}

	/**
	 * 配置不拦截静态资源
	 * @param web
	 * @throws Exception
	 */
	@Override
	public void configure(WebSecurity web) throws Exception {
		// 解决静态资源被拦截的问题
		web.ignoring().antMatchers("/assets/**");
		web.ignoring().antMatchers("/favicon.ico");
	}

}
